package net.keebook.webapp.util;

import java.util.Map;
import java.util.TimeZone;

import javax.inject.Inject;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import net.keebook.webapp.dao.SettingDao;
import net.keebook.webapp.dao.UserDao;
import net.keebook.webapp.entity.Setting;
import net.keebook.webapp.entity.User;

import org.apache.log4j.Logger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;


@WebListener
public class ContextListener implements ServletContextListener {
	private Scheduler scheduler = null;
	@Inject
	private UserDao userDao;
	@Inject
	private SettingDao settingDao;
	
	@Override
	public void contextDestroyed(ServletContextEvent event) {
		if (scheduler != null) {
			try {
				scheduler.shutdown();
			} catch (SchedulerException e) {
				Logger.getLogger(this.getClass()).warn("Error while shutting down scheduler", e);
			}
		}
	}

	@Override
	public void contextInitialized(ServletContextEvent event) {
		Logger.getLogger(this.getClass()).info("Initializing application");
		
		// Check default settings
		Map<SettingId, Setting> settings = getSettingDao().getMap();
		if (!settings.containsKey(SettingId.PASSWORD_LOGIN)) {
			getSettingDao().store(new Setting(SettingId.PASSWORD_LOGIN, true));
		}
		if (!settings.containsKey(SettingId.FACEBOOK_LOGIN)) {
			getSettingDao().store(new Setting(SettingId.FACEBOOK_LOGIN, false));
		}
		if (!settings.containsKey(SettingId.GOOGLE_LOGIN)) {
			getSettingDao().store(new Setting(SettingId.GOOGLE_LOGIN, false));
		}
		if (!settings.containsKey(SettingId.TWITTER_LOGIN)) {
			getSettingDao().store(new Setting(SettingId.TWITTER_LOGIN, false));
		}
		if (!settings.containsKey(SettingId.SYSTEM_TIMEZONE)) {
			getSettingDao().store(new Setting(SettingId.SYSTEM_TIMEZONE, TimeZone.getDefault().getID()));
		}
		if (!settings.containsKey(SettingId.ALLOW_SIGNUP)) {
			getSettingDao().store(new Setting(SettingId.ALLOW_SIGNUP, false));
		}
		if (!settings.containsKey(SettingId.PUBLIC_URL)) {
			String url = "http://localhost:8080" + event.getServletContext().getContextPath();
			getSettingDao().store(new Setting(SettingId.PUBLIC_URL, url));
		}
		if (!settings.containsKey(SettingId.SMTP_HOST)) {
			getSettingDao().store(new Setting(SettingId.SMTP_HOST, "localhost"));
		}
		if (!settings.containsKey(SettingId.SMTP_PORT)) {
			getSettingDao().store(new Setting(SettingId.SMTP_PORT, 25l));
		}
		if (!settings.containsKey(SettingId.SMTP_ENABLE)) {
			getSettingDao().store(new Setting(SettingId.SMTP_ENABLE, false));
		}
		if (!settings.containsKey(SettingId.SMTP_AUTH)) {
			getSettingDao().store(new Setting(SettingId.SMTP_AUTH, false));
		}
		if (!settings.containsKey(SettingId.SMTP_USERNAME)) {
			getSettingDao().store(new Setting(SettingId.SMTP_USERNAME, ""));
		}
		if (!settings.containsKey(SettingId.SMTP_PASSWORD)) {
			getSettingDao().store(new Setting(SettingId.SMTP_PASSWORD, ""));
		}
		if (!settings.containsKey(SettingId.SMTP_SENDER_ADDRESS)) {
			getSettingDao().store(new Setting(SettingId.SMTP_SENDER_ADDRESS, "null@dev.null"));
		}
		if (!settings.containsKey(SettingId.FACEBOOK_APP_ID)) {
			getSettingDao().store(new Setting(SettingId.FACEBOOK_APP_ID, ""));
		}
		if (!settings.containsKey(SettingId.FACEBOOK_APP_SECRET)) {
			getSettingDao().store(new Setting(SettingId.FACEBOOK_APP_SECRET, ""));
		}
		if (!settings.containsKey(SettingId.GOOGLE_CLIENT_ID)) {
			getSettingDao().store(new Setting(SettingId.GOOGLE_CLIENT_ID, ""));
		}
		if (!settings.containsKey(SettingId.GOOGLE_CLIENT_SECRET)) {
			getSettingDao().store(new Setting(SettingId.GOOGLE_CLIENT_SECRET, ""));
		}
		if (!settings.containsKey(SettingId.TWITTER_CONSUMER_KEY)) {
			getSettingDao().store(new Setting(SettingId.TWITTER_CONSUMER_KEY, ""));
		}
		if (!settings.containsKey(SettingId.TWITTER_CONSUMER_SECRET)) {
			getSettingDao().store(new Setting(SettingId.TWITTER_CONSUMER_SECRET, ""));
		}
		
		// Check if initial user must be created
		if (getUserDao().getList().isEmpty()) {
			Logger.getLogger(this.getClass()).info("Creating initial admin account");
			
			User user = new User();
			user.setAdmin(true);
			user.setUsername("admin");
			user.setTimezone(TimeZone.getDefault().getID());
			user.setHashedPassword(BCrypt.hashpw("admin", BCrypt.gensalt()));
			user.setEnabled(true);
			user.setConfirmed(true);
			getUserDao().store(user);
		}
		
		// Setting up scheduled jobs
		try {
			scheduler = StdSchedulerFactory.getDefaultScheduler();
			scheduler.start();
			
			JobDetail checkSubscriptionsJob = newJob(CheckSubscriptions.class).withIdentity("checkSubscriptionsJob").build();
			Trigger trigger = newTrigger().withIdentity("checkSubscriptionsTrigger").startNow().withSchedule(simpleSchedule().withIntervalInHours(1).repeatForever()).build();
			scheduler.scheduleJob(checkSubscriptionsJob, trigger);
		} catch (SchedulerException e) {
			Logger.getLogger(this.getClass()).warn("Error while scheduling jobs", e);
		}
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public SettingDao getSettingDao() {
		return settingDao;
	}

	public void setSettingDao(SettingDao settingDao) {
		this.settingDao = settingDao;
	}
}
